package c_Lock;


import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


/**
 * 锁测试类，演示如何使用ReentrantLock进行线程同步。
 *
 * @author Cheng-02
 * @version V1.0
 * @Package c_Lock
 * @date 2024/4/7 下午7:54
 */
public class LockTest {

    public static void main(String[] args) {
        // 创建一个售票对象
        myThread t1 = new myThread();
        // 使用同一个售票对象创建三个售票窗口线程
        Thread t2 = new Thread(t1, "窗口1");
        Thread t3 = new Thread(t1, "窗口2");
        Thread t4 = new Thread(t1, "窗口3");
        // 启动三个售票窗口线程
        t2.start();
        t3.start();
        t4.start();
    }
}

/**
 * 模拟售票窗口的线程类。
 * 每个实例都可以作为一个售票窗口，进行售票操作。
 */
class myThread extends Thread {
    int ticket = 100; // 售票数量
    Lock lock = new ReentrantLock(); // 创建锁对象

    /**
     * 线程的运行方法，用于模拟售票过程。
     * 通过循环不断进行售票操作，直到票数售完。
     */
    public void run() {
        while (true) {
            try {
                // 模拟售票动作的间隔时间
                Thread.sleep(100L);

                // 获取锁，确保线程安全
                lock.lock();
                System.out.println(Thread.currentThread().getName() + "进入同步块，准备售票");
                if (ticket > 0) {
                    // 进行售票操作
                    System.out.println(Thread.currentThread().getName() + "正在买第" + ticket + "张票");
                    ticket--; // 出售一张票
                }
                if (ticket == 0) {
                    // 票售完后结束线程
                    System.out.println("票已售完");
                    break;
                }
                System.out.println(Thread.currentThread().getName() + "完成售票，离开同步块");

            } catch (InterruptedException e) {
                // 处理线程中断异常
                throw new RuntimeException(e);
            } finally {
                // 释放锁，确保锁能被其他线程获取
                lock.unlock();
            }
        }
    }
}

